Rename GtkCssRBTree to GtkRBTree
authorMatthias Clasen <mclasen@redhat.com>
Mon, 7 Jan 2019 04:37:32 +0000 (23:37 -0500)
committerBenjamin Otte <otte@redhat.com>
Mon, 14 Jan 2019 01:14:11 +0000 (02:14 +0100)
This is a generally usable red-black tree api,
and it is not used in css at all.

13 files changed:
gtk/gtkcssrbtree.c [deleted file]
gtk/gtkcssrbtreeprivate.h [deleted file]
gtk/gtkfilterlistmodel.c
gtk/gtkflattenlistmodel.c
gtk/gtkmaplistmodel.c
gtk/gtkrbtree.c [new file with mode: 0644]
gtk/gtkrbtreeprivate.h [new file with mode: 0644]
gtk/gtkslicelistmodel.c
gtk/gtktreelistmodel.c
gtk/meson.build
testsuite/gtk/cssrbtree-crash.c [deleted file]
testsuite/gtk/meson.build
testsuite/gtk/rbtree-crash.c [new file with mode: 0644]

diff --git a/gtk/gtkcssrbtree.c b/gtk/gtkcssrbtree.c
deleted file mode 100644 (file)
index d791f04..0000000
+++ /dev/null
@@ -1,761 +0,0 @@
-/* gtkrbtree.c
- * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include "gtkcssrbtreeprivate.h"
-
-#include "gtkdebug.h"
-
-typedef struct _GtkCssRbNode GtkCssRbNode;
-
-struct _GtkCssRbTree
-{
-  guint ref_count;
-
-  gsize element_size;
-  gsize augment_size;
-  GtkCssRbTreeAugmentFunc augment_func;
-  GDestroyNotify clear_func;
-  GDestroyNotify clear_augment_func;
-
-  GtkCssRbNode *root;
-};
-
-struct _GtkCssRbNode
-{
-  guint red :1;
-  guint dirty :1;
-
-  GtkCssRbNode *left;
-  GtkCssRbNode *right;
-  GtkCssRbNode *parent;
-};
-
-#define NODE_FROM_POINTER(ptr) ((GtkCssRbNode *) ((ptr) ? (((guchar *) (ptr)) - sizeof (GtkCssRbNode)) : NULL))
-#define NODE_TO_POINTER(node) ((gpointer) ((node) ? (((guchar *) (node)) + sizeof (GtkCssRbNode)) : NULL))
-#define NODE_TO_AUG_POINTER(tree, node) ((gpointer) ((node) ? (((guchar *) (node)) + sizeof (GtkCssRbNode) + (tree)->element_size) : NULL))
-
-static inline gsize
-gtk_css_rb_node_get_size (GtkCssRbTree *tree)
-{
-  return sizeof (GtkCssRbNode) + tree->element_size + tree->augment_size;
-}
-
-static GtkCssRbNode *
-gtk_css_rb_node_new (GtkCssRbTree *tree)
-{
-  GtkCssRbNode *result;
-
-  result = g_slice_alloc0 (gtk_css_rb_node_get_size (tree));
-
-  result->red = TRUE;
-  result->dirty = TRUE;
-
-  return result;
-}
-
-static void
-gtk_css_rb_node_free (GtkCssRbTree *tree,
-                      GtkCssRbNode *node)
-{
-  if (tree->clear_func)
-    tree->clear_func (NODE_TO_POINTER (node));
-  if (tree->clear_augment_func)
-    tree->clear_augment_func (NODE_TO_AUG_POINTER (tree, node));
-
-  g_slice_free1 (gtk_css_rb_node_get_size (tree), node);
-}
-
-static void
-gtk_css_rb_node_free_deep (GtkCssRbTree *tree,
-                           GtkCssRbNode *node)
-{
-  GtkCssRbNode *right = node->right;
-
-  if (node->left)
-    gtk_css_rb_node_free_deep (tree, node->left);
-
-  gtk_css_rb_node_free (tree, node);
-
-  if (right)
-    gtk_css_rb_node_free_deep (tree, right);
-}
-
-static void
-gtk_css_rb_node_mark_dirty (GtkCssRbNode *node,
-                            gboolean      mark_parent)
-{
-  if (node->dirty)
-    return;
-  
-  node->dirty = TRUE;
-
-  if (mark_parent && node->parent)
-    gtk_css_rb_node_mark_dirty (node->parent, TRUE);
-}
-
-static void
-gtk_css_rb_node_clean (GtkCssRbTree *tree,
-                       GtkCssRbNode *node)
-{
-  if (!node->dirty)
-    return;
-
-  node->dirty = FALSE;
-  if (tree->augment_func)
-    tree->augment_func (tree,
-                        NODE_TO_AUG_POINTER (tree, node),
-                        NODE_TO_POINTER (node),
-                        NODE_TO_POINTER (node->left),
-                        NODE_TO_POINTER (node->right));
-}
-
-static GtkCssRbNode *
-gtk_css_rb_node_get_first (GtkCssRbNode *node)
-{
-  while (node->left)
-    node = node->left;
-
-  return node;
-}
-
-static GtkCssRbNode *
-gtk_css_rb_node_get_last (GtkCssRbNode *node)
-{
-  while (node->right)
-    node = node->right;
-
-  return node;
-}
-
-static GtkCssRbNode *
-gtk_css_rb_node_get_previous (GtkCssRbNode *node)
-{
-  GtkCssRbNode *parent;
-
-  if (node->left)
-    return gtk_css_rb_node_get_last (node->left);
-
-  for (parent = node->parent; parent != NULL; parent = node->parent)
-    {
-      if (parent->right == node)
-        return parent;
-
-      node = parent;
-    }
-
-  return NULL;
-}
-
-static GtkCssRbNode *
-gtk_css_rb_node_get_next (GtkCssRbNode *node)
-{
-  GtkCssRbNode *parent;
-
-  if (node->right)
-    return gtk_css_rb_node_get_first (node->right);
-
-  for (parent = node->parent; parent != NULL; parent = node->parent)
-    {
-      if (parent->left == node)
-        return parent;
-
-      node = parent;
-    }
-
-  return NULL;
-}
-
-static void
-gtk_css_rb_node_rotate_left (GtkCssRbTree *tree,
-                             GtkCssRbNode *node)
-{
-  GtkCssRbNode *right;
-
-  right = node->right;
-
-  node->right = right->left;
-  if (right->left)
-    right->left->parent = node;
-
-  right->parent = node->parent;
-  if (node->parent)
-    {
-      if (node == node->parent->left)
-       node->parent->left = right;
-      else
-       node->parent->right = right;
-    }
-  else
-    {
-      tree->root = right;
-    }
-
-  right->left = node;
-  node->parent = right;
-
-  gtk_css_rb_node_mark_dirty (node, FALSE);
-  gtk_css_rb_node_mark_dirty (right, FALSE);
-}
-
-static void
-gtk_css_rb_node_rotate_right (GtkCssRbTree *tree,
-                              GtkCssRbNode *node)
-{
-  GtkCssRbNode *left;
-
-  left = node->left;
-
-  node->left = left->right;
-  if (left->right)
-    left->right->parent = node;
-
-  left->parent = node->parent;
-  if (node->parent)
-    {
-      if (node == node->parent->right)
-       node->parent->right = left;
-      else
-       node->parent->left = left;
-    }
-  else
-    {
-      tree->root = left;
-    }
-
-  /* link node and left */
-  left->right = node;
-  node->parent = left;
-
-  gtk_css_rb_node_mark_dirty (node, FALSE);
-  gtk_css_rb_node_mark_dirty (left, FALSE);
-}
-
-static gboolean
-is_red (GtkCssRbNode *node_or_null)
-{
-  if (node_or_null == NULL)
-    return FALSE;
-  else
-    return node_or_null->red;
-}
-
-static inline gboolean
-is_black (GtkCssRbNode *node_or_null)
-{
-  return !is_red (node_or_null);
-}
-
-static void
-set_black (GtkCssRbNode *node_or_null)
-{
-  if (node_or_null == NULL)
-    return;
-
-  node_or_null->red = FALSE;
-}
-
-static void
-set_red (GtkCssRbNode *node_or_null)
-{
-  if (node_or_null == NULL)
-    return;
-
-  node_or_null->red = TRUE;
-}
-
-static void
-gtk_css_rb_tree_insert_fixup (GtkCssRbTree *tree,
-                              GtkCssRbNode *node)
-{
-
-  /* check Red-Black properties */
-  while (node->parent && is_red (node->parent))
-    {
-      /* we have a violation */
-      g_assert (node->parent->parent);
-
-      if (node->parent == node->parent->parent->left)
-       {
-         GtkCssRbNode *uncle = node->parent->parent->right;
-
-         if (is_red (uncle))
-           {
-             /* uncle is red */
-             set_black (node->parent);
-              set_black (uncle);
-              set_red (node->parent->parent);
-             node = node->parent->parent;
-           }
-         else
-           {
-             /* uncle is black */
-             if (node == node->parent->right)
-               {
-                 /* make node a left child */
-                 node = node->parent;
-                 gtk_css_rb_node_rotate_left (tree, node);
-               }
-             /* recolor and rotate */
-              set_black (node->parent);
-              set_red (node->parent->parent);
-             gtk_css_rb_node_rotate_right (tree, node->parent->parent);
-           }
-       }
-      else
-       {
-         /* mirror image of above code */
-         GtkCssRbNode *uncle = node->parent->parent->left;
-
-         if (is_red (uncle))
-           {
-             /* uncle is red */
-              set_black (node->parent);
-              set_black (uncle);
-              set_red (node->parent->parent);
-             node = node->parent->parent;
-           }
-         else
-           {
-              /* uncle is black */
-             if (node == node->parent->left)
-               {
-                 node = node->parent;
-                 gtk_css_rb_node_rotate_right (tree, node);
-               }
-             set_black (node->parent);
-             set_red (node->parent->parent);
-             gtk_css_rb_node_rotate_left (tree, node->parent->parent);
-           }
-       }
-    }
-
-  set_black (tree->root);
-}
-
-static void
-gtk_css_rb_tree_remove_node_fixup (GtkCssRbTree *tree,
-                                   GtkCssRbNode *node,
-                                   GtkCssRbNode *parent)
-{
-  while (node != tree->root && is_black (node))
-    {
-      if (node == parent->left)
-       {
-         GtkCssRbNode *w = parent->right;
-
-         if (is_red (w))
-           {
-             set_black (w);
-              set_red (parent);
-             gtk_css_rb_node_rotate_left (tree, parent);
-             w = parent->right;
-           }
-         if (is_black (w->left) && is_black (w->right))
-           {
-             set_red (w);
-             node = parent;
-           }
-         else
-           {
-             if (is_black (w->right))
-               {
-                 set_black (w->left);
-                 set_red (w);
-                 gtk_css_rb_node_rotate_right (tree, w);
-                 w = parent->right;
-               }
-             w->red = parent->red;
-             set_black (parent);
-              set_black (w->right);
-             gtk_css_rb_node_rotate_left (tree, parent);
-             node = tree->root;
-           }
-       }
-      else
-       {
-         GtkCssRbNode *w = parent->left;
-         if (is_red (w))
-           {
-             set_black (w);
-             set_red (parent);
-             gtk_css_rb_node_rotate_right (tree, parent);
-             w = parent->left;
-           }
-         if (is_black (w->right) && is_black (w->left))
-           {
-             set_red (w);
-             node = parent;
-           }
-         else
-           {
-             if (is_black (w->left))
-               {
-                 set_black (w->right);
-                 set_red (w);
-                 gtk_css_rb_node_rotate_left (tree, w);
-                 w = parent->left;
-               }
-             w->red = parent->red;
-             set_black (parent);
-             set_black (w->left);
-             gtk_css_rb_node_rotate_right (tree, parent);
-             node = tree->root;
-           }
-       }
-
-      parent = node->parent;
-    }
-
-  set_black (node);
-}
-
-GtkCssRbTree *
-gtk_css_rb_tree_new_for_size (gsize                   element_size,
-                              gsize                   augment_size,
-                              GtkCssRbTreeAugmentFunc augment_func,
-                              GDestroyNotify          clear_func,
-                              GDestroyNotify          clear_augment_func)
-{
-  GtkCssRbTree *tree;
-
-  tree = g_slice_new0 (GtkCssRbTree);
-  tree->ref_count = 1;
-
-  tree->element_size = element_size;
-  tree->augment_size = augment_size;
-  tree->augment_func = augment_func;
-  tree->clear_func = clear_func;
-  tree->clear_augment_func = clear_augment_func;
-
-  return tree;
-}
-
-GtkCssRbTree *
-gtk_css_rb_tree_ref (GtkCssRbTree *tree)
-{
-  tree->ref_count++;
-
-  return tree;
-}
-
-void
-gtk_css_rb_tree_unref (GtkCssRbTree *tree)
-{
-  tree->ref_count--;
-  if (tree->ref_count > 0)
-    return;
-
-  if (tree->root)
-    gtk_css_rb_node_free_deep (tree, tree->root);
-    
-  g_slice_free (GtkCssRbTree, tree);
-}
-
-gpointer
-gtk_css_rb_tree_get_first (GtkCssRbTree *tree)
-{
-  if (tree->root == NULL)
-    return NULL;
-
-  return NODE_TO_POINTER (gtk_css_rb_node_get_first (tree->root));
-}
-
-gpointer
-gtk_css_rb_tree_get_last (GtkCssRbTree *tree)
-{
-  if (tree->root == NULL)
-    return NULL;
-
-  return NODE_TO_POINTER (gtk_css_rb_node_get_last (tree->root));
-}
-
-gpointer
-gtk_css_rb_tree_get_previous (GtkCssRbTree *tree,
-                              gpointer      node)
-{
-  return NODE_TO_POINTER (gtk_css_rb_node_get_previous (NODE_FROM_POINTER (node)));
-}
-
-gpointer
-gtk_css_rb_tree_get_next (GtkCssRbTree *tree,
-                          gpointer      node)
-{
-  return NODE_TO_POINTER (gtk_css_rb_node_get_next (NODE_FROM_POINTER (node)));
-}
-
-gpointer
-gtk_css_rb_tree_get_root (GtkCssRbTree *tree)
-{
-  return NODE_TO_POINTER (tree->root);
-}
-
-gpointer
-gtk_css_rb_tree_get_parent (GtkCssRbTree *tree,
-                            gpointer      node)
-{
-  return NODE_TO_POINTER (NODE_FROM_POINTER (node)->parent);
-}
-
-gpointer
-gtk_css_rb_tree_get_left (GtkCssRbTree *tree,
-                          gpointer      node)
-{
-  return NODE_TO_POINTER (NODE_FROM_POINTER (node)->left);
-}
-
-gpointer
-gtk_css_rb_tree_get_right (GtkCssRbTree *tree,
-                           gpointer      node)
-{
-  return NODE_TO_POINTER (NODE_FROM_POINTER (node)->right);
-}
-
-gpointer
-gtk_css_rb_tree_get_augment (GtkCssRbTree *tree,
-                             gpointer      node)
-{
-  GtkCssRbNode *rbnode = NODE_FROM_POINTER (node);
-
-  gtk_css_rb_node_clean (tree, rbnode);
-
-  return NODE_TO_AUG_POINTER (tree, rbnode);
-}
-
-void
-gtk_css_rb_tree_mark_dirty (GtkCssRbTree *tree,
-                            gpointer      node)
-{
-  gtk_css_rb_node_mark_dirty (NODE_FROM_POINTER (node), TRUE);
-}
-
-gpointer
-gtk_css_rb_tree_insert_before (GtkCssRbTree *tree,
-                              gpointer      node)
-{
-  GtkCssRbNode *result;
-
-  /* setup new node */
-  result = gtk_css_rb_node_new (tree);
-
-  if (tree->root == NULL)
-    {
-      g_assert (node == NULL);
-      tree->root = result;
-    }
-  else if (node == NULL)
-    {
-      return gtk_css_rb_tree_insert_after (tree, gtk_css_rb_tree_get_last (tree));
-    }
-  else
-    {
-      GtkCssRbNode *current = NODE_FROM_POINTER (node);
-
-      if (current->left)
-        {
-          current = gtk_css_rb_node_get_last (current->left);
-          current->right = result;
-        }
-      else
-        {
-          current->left = result;
-        }
-      result->parent = current;
-      gtk_css_rb_node_mark_dirty (current, TRUE);
-    }
-
-  gtk_css_rb_tree_insert_fixup (tree, result);
-
-  return NODE_TO_POINTER (result);
-}
-
-gpointer
-gtk_css_rb_tree_insert_after (GtkCssRbTree *tree,
-                             gpointer      node)
-{
-  GtkCssRbNode *result;
-
-  /* setup new node */
-  result = gtk_css_rb_node_new (tree);
-
-  if (tree->root == NULL)
-    {
-      g_assert (node == NULL);
-      tree->root = result;
-    }
-  else if (node == NULL)
-    {
-      return gtk_css_rb_tree_insert_before (tree, gtk_css_rb_tree_get_first (tree));
-    }
-  else
-    {
-      GtkCssRbNode *current = NODE_FROM_POINTER (node);
-
-      if (current->right)
-        {
-          current = gtk_css_rb_node_get_first (current->right);
-          current->left = result;
-        }
-      else
-        {
-          current->right = result;
-        }
-      result->parent = current;
-      gtk_css_rb_node_mark_dirty (current, TRUE);
-    }
-
-  gtk_css_rb_tree_insert_fixup (tree, result);
-
-  return NODE_TO_POINTER (result);
-}
-
-void
-gtk_css_rb_tree_remove (GtkCssRbTree *tree,
-                        gpointer      node)
-{
-  GtkCssRbNode *x, *y, *real_node;
-  
-  real_node = NODE_FROM_POINTER (node);
-  y = real_node;
-  if (y->left && y->right)
-    {
-      y = y->right;
-
-      while (y->left)
-       y = y->left;
-    }
-
-  /* x is y's only child, or nil */
-  if (y->left)
-    x = y->left;
-  else
-    x = y->right;
-
-  /* remove y from the parent chain */
-  if (x != NULL)
-    x->parent = y->parent;
-  if (y->parent)
-    {
-      if (y == y->parent->left)
-       y->parent->left = x;
-      else
-       y->parent->right = x;
-      gtk_css_rb_node_mark_dirty (y->parent, TRUE);
-    }
-  else
-    {
-      tree->root = x;
-    }
-
-  /* We need to clean up the validity of the tree.
-   */
-  if (is_black (y))
-    gtk_css_rb_tree_remove_node_fixup (tree, x, y->parent);
-
-  if (y != real_node)
-    {
-      /* Move the node over */
-      if (is_red (real_node) != is_red (y))
-       y->red = !y->red;
-
-      y->left = real_node->left;
-      if (y->left)
-        y->left->parent = y;
-      y->right = real_node->right;
-      if (y->right)
-        y->right->parent = y;
-      y->parent = real_node->parent;
-      if (y->parent)
-        {
-          if (y->parent->left == real_node)
-            y->parent->left = y;
-          else
-            y->parent->right = y;
-          gtk_css_rb_node_mark_dirty (y->parent, TRUE);
-        }
-      else
-        {
-          tree->root = y;
-        }
-      gtk_css_rb_node_mark_dirty (y, TRUE);
-    }
-
-  gtk_css_rb_node_free (tree, real_node);
-}
-
-void
-gtk_css_rb_tree_remove_all (GtkCssRbTree *tree)
-{
-  if (tree->root)
-    gtk_css_rb_node_free_deep (tree, tree->root);
-
-  tree->root = NULL;
-}
-
-gpointer
-gtk_css_rb_tree_find (GtkCssRbTree           *tree,
-                      gpointer               *out_before,
-                      gpointer               *out_after,
-                      GtkCssRbTreeFindFunc    find_func,
-                      gpointer                user_data)
-{
-  GtkCssRbNode *node, *before = NULL, *after = NULL;
-  int cmp;
-
-  if (tree->root == NULL)
-    {
-      if (out_before)
-        *out_before = NULL;
-      if (out_after)
-        *out_after = NULL;
-
-      return NULL;
-    }
-
-  node = tree->root;
-  for (cmp = find_func (tree, NODE_TO_POINTER (node), user_data);
-       cmp != 0;
-       cmp = find_func (tree, NODE_TO_POINTER (node), user_data))
-    {
-      if (cmp < 0)
-        {
-          before = node;
-          node = node->right;
-        }
-      else /* cmp > 0 */
-        {
-          after = node;
-          node = node->left;
-        }
-      if (node == NULL)
-        {
-          if (out_before)
-            *out_before = NODE_TO_POINTER (before);
-          if (out_after)
-            *out_after = NODE_TO_POINTER (after);
-          return NULL;;
-        }
-    }
-
-  if (out_before)
-    *out_before = NODE_TO_POINTER (gtk_css_rb_node_get_previous (node));
-  if (out_after)
-    *out_after = NODE_TO_POINTER (gtk_css_rb_node_get_next (node));
-
-  return NODE_TO_POINTER (node);
-}
diff --git a/gtk/gtkcssrbtreeprivate.h b/gtk/gtkcssrbtreeprivate.h
deleted file mode 100644 (file)
index f80108d..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/* gtkrb_tree.h
- * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* A Red-Black Tree implementation used specifically by GtkTreeView.
- */
-#ifndef __GTK_CSS_RB_TREE_H__
-#define __GTK_CSS_RB_TREE_H__
-
-#include <glib.h>
-
-
-G_BEGIN_DECLS
-
-
-typedef struct _GtkCssRbTree GtkCssRbTree;
-
-typedef void            (* GtkCssRbTreeAugmentFunc)     (GtkCssRbTree           *tree,
-                                                         gpointer                node_augment,
-                                                         gpointer                node,
-                                                         gpointer                left,
-                                                         gpointer                right);
-typedef int             (* GtkCssRbTreeFindFunc)        (GtkCssRbTree           *tree,
-                                                         gpointer                node,
-                                                         gpointer                user_data);
-
-GtkCssRbTree *          gtk_css_rb_tree_new_for_size    (gsize                   element_size,
-                                                         gsize                   augment_size,
-                                                         GtkCssRbTreeAugmentFunc augment_func,
-                                                         GDestroyNotify          clear_func,
-                                                         GDestroyNotify          clear_augment_func);
-#define gtk_css_rb_tree_new(type, augment_type, augment_func, clear_func, clear_augment_func) \
-  gtk_css_rb_tree_new_for_size (sizeof (type), sizeof (augment_type), (augment_func), (clear_func), (clear_augment_func))
-
-GtkCssRbTree *          gtk_css_rb_tree_ref             (GtkCssRbTree           *tree);
-void                    gtk_css_rb_tree_unref           (GtkCssRbTree           *tree);
-
-gpointer                gtk_css_rb_tree_get_first       (GtkCssRbTree           *tree);
-gpointer                gtk_css_rb_tree_get_last        (GtkCssRbTree           *tree);
-gpointer                gtk_css_rb_tree_get_previous    (GtkCssRbTree           *tree,
-                                                         gpointer                node);
-gpointer                gtk_css_rb_tree_get_next        (GtkCssRbTree           *tree,
-                                                         gpointer                node);
-
-gpointer                gtk_css_rb_tree_get_root        (GtkCssRbTree           *tree);
-gpointer                gtk_css_rb_tree_get_parent      (GtkCssRbTree           *tree,
-                                                         gpointer                node);
-gpointer                gtk_css_rb_tree_get_left        (GtkCssRbTree           *tree,
-                                                         gpointer                node);
-gpointer                gtk_css_rb_tree_get_right       (GtkCssRbTree           *tree,
-                                                         gpointer                node);
-gpointer                gtk_css_rb_tree_get_augment     (GtkCssRbTree           *tree,
-                                                         gpointer                node);
-
-void                    gtk_css_rb_tree_mark_dirty      (GtkCssRbTree           *tree,
-                                                         gpointer                node);
-
-gpointer                gtk_css_rb_tree_insert_before   (GtkCssRbTree           *tree,
-                                                         gpointer                node);
-gpointer                gtk_css_rb_tree_insert_after    (GtkCssRbTree           *tree,
-                                                         gpointer                node);
-void                    gtk_css_rb_tree_remove          (GtkCssRbTree           *tree,
-                                                         gpointer                node);
-void                    gtk_css_rb_tree_remove_all      (GtkCssRbTree           *tree);
-
-gpointer                gtk_css_rb_tree_find            (GtkCssRbTree           *tree,
-                                                         gpointer               *out_before,
-                                                         gpointer               *out_after,
-                                                         GtkCssRbTreeFindFunc    find_func,
-                                                         gpointer                user_data);
-
-
-
-G_END_DECLS
-
-
-#endif /* __GTK_CSS_RB_TREE_H__ */
index bf2ced74e59b135de403c7d92b21bb3c55ae9109..aa5abe8df21cbc3aa33aa05854efd40ef2e8a23b 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "gtkfilterlistmodel.h"
 
-#include "gtkcssrbtreeprivate.h"
+#include "gtkrbtreeprivate.h"
 #include "gtkintl.h"
 #include "gtkprivate.h"
 
@@ -69,7 +69,7 @@ struct _GtkFilterListModel
   gpointer user_data;
   GDestroyNotify user_destroy;
 
-  GtkCssRbTree *items; /* NULL if filter_func == NULL */
+  GtkRbTree *items; /* NULL if filter_func == NULL */
 };
 
 struct _GtkFilterListModelClass
@@ -80,22 +80,22 @@ struct _GtkFilterListModelClass
 static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
 
 static FilterNode *
-gtk_filter_list_model_get_nth_filtered (GtkCssRbTree *tree,
-                                        guint         position,
-                                        guint        *out_unfiltered)
+gtk_filter_list_model_get_nth_filtered (GtkRbTree *tree,
+                                        guint      position,
+                                        guint     *out_unfiltered)
 {
   FilterNode *node, *tmp;
   guint unfiltered;
 
-  node = gtk_css_rb_tree_get_root (tree);
+  node = gtk_rb_tree_get_root (tree);
   unfiltered = 0;
 
   while (node)
     {
-      tmp = gtk_css_rb_tree_get_left (tree, node);
+      tmp = gtk_rb_tree_get_left (tree, node);
       if (tmp)
         {
-          FilterAugment *aug = gtk_css_rb_tree_get_augment (tree, tmp);
+          FilterAugment *aug = gtk_rb_tree_get_augment (tree, tmp);
           if (position < aug->n_visible)
             {
               node = tmp;
@@ -114,7 +114,7 @@ gtk_filter_list_model_get_nth_filtered (GtkCssRbTree *tree,
 
       unfiltered++;
 
-      node = gtk_css_rb_tree_get_right (tree, node);
+      node = gtk_rb_tree_get_right (tree, node);
     }
 
   if (out_unfiltered)
@@ -124,22 +124,22 @@ gtk_filter_list_model_get_nth_filtered (GtkCssRbTree *tree,
 }
 
 static FilterNode *
-gtk_filter_list_model_get_nth (GtkCssRbTree *tree,
-                               guint         position,
-                               guint        *out_filtered)
+gtk_filter_list_model_get_nth (GtkRbTree *tree,
+                               guint      position,
+                               guint     *out_filtered)
 {
   FilterNode *node, *tmp;
   guint filtered;
 
-  node = gtk_css_rb_tree_get_root (tree);
+  node = gtk_rb_tree_get_root (tree);
   filtered = 0;
 
   while (node)
     {
-      tmp = gtk_css_rb_tree_get_left (tree, node);
+      tmp = gtk_rb_tree_get_left (tree, node);
       if (tmp)
         {
-          FilterAugment *aug = gtk_css_rb_tree_get_augment (tree, tmp);
+          FilterAugment *aug = gtk_rb_tree_get_augment (tree, tmp);
           if (position < aug->n_items)
             {
               node = tmp;
@@ -156,7 +156,7 @@ gtk_filter_list_model_get_nth (GtkCssRbTree *tree,
       if (node->visible)
         filtered++;
 
-      node = gtk_css_rb_tree_get_right (tree, node);
+      node = gtk_rb_tree_get_right (tree, node);
     }
 
   if (out_filtered)
@@ -186,11 +186,11 @@ gtk_filter_list_model_get_n_items (GListModel *list)
   if (!self->items)
     return g_list_model_get_n_items (self->model);
 
-  node = gtk_css_rb_tree_get_root (self->items);
+  node = gtk_rb_tree_get_root (self->items);
   if (node == NULL)
     return 0;
 
-  aug = gtk_css_rb_tree_get_augment (self->items, node);
+  aug = gtk_rb_tree_get_augment (self->items, node);
   return aug->n_visible;
 }
 
@@ -250,7 +250,7 @@ gtk_filter_list_model_add_items (GtkFilterListModel *self,
   
   for (i = 0; i < n_items; i++)
     {
-      node = gtk_css_rb_tree_insert_before (self->items, after);
+      node = gtk_rb_tree_insert_before (self->items, after);
       node->visible = gtk_filter_list_model_run_filter (self, position + i);
       if (node->visible)
         n_visible++;
@@ -280,10 +280,10 @@ gtk_filter_list_model_items_changed_cb (GListModel         *model,
   filter_removed = 0;
   for (i = 0; i < removed; i++)
     {
-      FilterNode *next = gtk_css_rb_tree_get_next (self->items, node);
+      FilterNode *next = gtk_rb_tree_get_next (self->items, node);
       if (node->visible)
         filter_removed++;
-      gtk_css_rb_tree_remove (self->items, node);
+      gtk_rb_tree_remove (self->items, node);
       node = next;
     }
 
@@ -354,7 +354,7 @@ gtk_filter_list_model_clear_model (GtkFilterListModel *self)
   g_signal_handlers_disconnect_by_func (self->model, gtk_filter_list_model_items_changed_cb, self);
   g_clear_object (&self->model);
   if (self->items)
-    gtk_css_rb_tree_remove_all (self->items);
+    gtk_rb_tree_remove_all (self->items);
 }
 
 static void
@@ -368,10 +368,10 @@ gtk_filter_list_model_dispose (GObject *object)
   self->filter_func = NULL;
   self->user_data = NULL;
   self->user_destroy = NULL;
-  g_clear_pointer (&self->items, gtk_css_rb_tree_unref);
+  g_clear_pointer (&self->items, gtk_rb_tree_unref);
 
   G_OBJECT_CLASS (gtk_filter_list_model_parent_class)->dispose (object);
-};
+}
 
 static void
 gtk_filter_list_model_class_init (GtkFilterListModelClass *class)
@@ -428,13 +428,13 @@ gtk_filter_list_model_init (GtkFilterListModel *self)
 
 
 static void
-gtk_filter_list_model_augment (GtkCssRbTree *filter,
-                               gpointer      _aug,
-                               gpointer      _node,
-                               gpointer      left,
-                               gpointer      right)
+gtk_filter_list_model_augment (GtkRbTree *filter,
+                               gpointer   _aug,
+                               gpointer   _node,
+                               gpointer   left,
+                               gpointer   right)
 {
-  FilterNode *node= _node;
+  FilterNode *node = _node;
   FilterAugment *aug = _aug;
 
   aug->n_items = 1;
@@ -442,13 +442,13 @@ gtk_filter_list_model_augment (GtkCssRbTree *filter,
 
   if (left)
     {
-      FilterAugment *left_aug = gtk_css_rb_tree_get_augment (filter, left);
+      FilterAugment *left_aug = gtk_rb_tree_get_augment (filter, left);
       aug->n_items += left_aug->n_items;
       aug->n_visible += left_aug->n_visible;
     }
   if (right)
     {
-      FilterAugment *right_aug = gtk_css_rb_tree_get_augment (filter, right);
+      FilterAugment *right_aug = gtk_rb_tree_get_augment (filter, right);
       aug->n_items += right_aug->n_items;
       aug->n_visible += right_aug->n_visible;
     }
@@ -543,22 +543,22 @@ gtk_filter_list_model_set_filter_func (GtkFilterListModel           *self,
   
   if (!will_be_filtered)
     {
-      g_clear_pointer (&self->items, gtk_css_rb_tree_unref);
+      g_clear_pointer (&self->items, gtk_rb_tree_unref);
     }
   else if (!was_filtered)
     {
       guint i, n_items;
 
-      self->items = gtk_css_rb_tree_new (FilterNode,
-                                         FilterAugment, 
-                                         gtk_filter_list_model_augment,
-                                         NULL, NULL);
+      self->items = gtk_rb_tree_new (FilterNode,
+                                     FilterAugment,
+                                     gtk_filter_list_model_augment,
+                                     NULL, NULL);
       if (self->model)
         {
           n_items = g_list_model_get_n_items (self->model);
           for (i = 0; i < n_items; i++)
             {
-              FilterNode *node = gtk_css_rb_tree_insert_before (self->items, NULL);
+              FilterNode *node = gtk_rb_tree_insert_before (self->items, NULL);
               node->visible = TRUE;
             }
         }
@@ -675,9 +675,9 @@ gtk_filter_list_model_refilter (GtkFilterListModel *self)
   last_change = 0;
   n_is_visible = 0;
   n_was_visible = 0;
-  for (i = 0, node = gtk_css_rb_tree_get_first (self->items);
+  for (i = 0, node = gtk_rb_tree_get_first (self->items);
        node != NULL;
-       i++, node = gtk_css_rb_tree_get_next (self->items, node))
+       i++, node = gtk_rb_tree_get_next (self->items, node))
     {
       visible = gtk_filter_list_model_run_filter (self, i);
       if (visible == node->visible)
@@ -691,7 +691,7 @@ gtk_filter_list_model_refilter (GtkFilterListModel *self)
         }
 
       node->visible = visible;
-      gtk_css_rb_tree_mark_dirty (self->items, node);
+      gtk_rb_tree_mark_dirty (self->items, node);
       first_change = MIN (n_is_visible, first_change);
       if (visible)
         n_is_visible++;
index b7066742b76e2a45c35c4ff4b596a195bae95fa0..58852061e296f840ea629b612598e6eb7a5a8a36 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "gtkflattenlistmodel.h"
 
-#include "gtkcssrbtreeprivate.h"
+#include "gtkrbtreeprivate.h"
 #include "gtkintl.h"
 #include "gtkprivate.h"
 
@@ -66,7 +66,7 @@ struct _GtkFlattenListModel
 
   GType item_type;
   GListModel *model;
-  GtkCssRbTree *items; /* NULL if model == NULL */
+  GtkRbTree *items; /* NULL if model == NULL */
 };
 
 struct _GtkFlattenListModelClass
@@ -77,21 +77,21 @@ struct _GtkFlattenListModelClass
 static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
 
 static FlattenNode *
-gtk_flatten_list_model_get_nth (GtkCssRbTree *tree,
+gtk_flatten_list_model_get_nth (GtkRbTree *tree,
                                 guint         position,
                                 guint        *model_position)
 {
   FlattenNode *node, *tmp;
   guint model_n_items;
 
-  node = gtk_css_rb_tree_get_root (tree);
+  node = gtk_rb_tree_get_root (tree);
 
   while (node)
     {
-      tmp = gtk_css_rb_tree_get_left (tree, node);
+      tmp = gtk_rb_tree_get_left (tree, node);
       if (tmp)
         {
-          FlattenAugment *aug = gtk_css_rb_tree_get_augment (tree, tmp);
+          FlattenAugment *aug = gtk_rb_tree_get_augment (tree, tmp);
           if (position < aug->n_items)
             {
               node = tmp;
@@ -105,7 +105,7 @@ gtk_flatten_list_model_get_nth (GtkCssRbTree *tree,
         break;
       position -= model_n_items;
 
-      node = gtk_css_rb_tree_get_right (tree, node);
+      node = gtk_rb_tree_get_right (tree, node);
     }
 
   if (model_position)
@@ -115,22 +115,22 @@ gtk_flatten_list_model_get_nth (GtkCssRbTree *tree,
 }
 
 static FlattenNode *
-gtk_flatten_list_model_get_nth_model (GtkCssRbTree *tree,
+gtk_flatten_list_model_get_nth_model (GtkRbTree *tree,
                                       guint         position,
                                       guint        *items_before)
 {
   FlattenNode *node, *tmp;
   guint before;
 
-  node = gtk_css_rb_tree_get_root (tree);
+  node = gtk_rb_tree_get_root (tree);
   before = 0;
 
   while (node)
     {
-      tmp = gtk_css_rb_tree_get_left (tree, node);
+      tmp = gtk_rb_tree_get_left (tree, node);
       if (tmp)
         {
-          FlattenAugment *aug = gtk_css_rb_tree_get_augment (tree, tmp);
+          FlattenAugment *aug = gtk_rb_tree_get_augment (tree, tmp);
           if (position < aug->n_models)
             {
               node = tmp;
@@ -145,7 +145,7 @@ gtk_flatten_list_model_get_nth_model (GtkCssRbTree *tree,
       position--;
       before += g_list_model_get_n_items (node->model);
 
-      node = gtk_css_rb_tree_get_right (tree, node);
+      node = gtk_rb_tree_get_right (tree, node);
     }
 
   if (items_before)
@@ -172,11 +172,11 @@ gtk_flatten_list_model_get_n_items (GListModel *list)
   if (!self->items)
     return 0;
 
-  node = gtk_css_rb_tree_get_root (self->items);
+  node = gtk_rb_tree_get_root (self->items);
   if (node == NULL)
     return 0;
 
-  aug = gtk_css_rb_tree_get_augment (self->items, node);
+  aug = gtk_rb_tree_get_augment (self->items, node);
   return aug->n_items;
 }
 
@@ -220,18 +220,18 @@ gtk_flatten_list_model_items_changed_cb (GListModel          *model,
   GtkFlattenListModel *self = node->list;
   guint real_position;
 
-  gtk_css_rb_tree_mark_dirty (self->items, node);
+  gtk_rb_tree_mark_dirty (self->items, node);
 
   for (real_position = position;
-       (parent = gtk_css_rb_tree_get_parent (self->items, node)) != NULL;
+       (parent = gtk_rb_tree_get_parent (self->items, node)) != NULL;
        node = parent)
     {
-      FlattenNode *left = gtk_css_rb_tree_get_left (self->items, parent);
+      FlattenNode *left = gtk_rb_tree_get_left (self->items, parent);
       if (left != node)
         {
           if (left)
             {
-              FlattenAugment *aug = gtk_css_rb_tree_get_augment (self->items, left);
+              FlattenAugment *aug = gtk_rb_tree_get_augment (self->items, left);
               real_position += aug->n_items;
             }
           real_position += g_list_model_get_n_items (parent->model);
@@ -251,13 +251,13 @@ gtk_flatten_list_model_clear_node (gpointer _node)
 }
 
 static void
-gtk_flatten_list_model_augment (GtkCssRbTree *flatten,
-                                gpointer      _aug,
-                                gpointer      _node,
-                                gpointer      left,
-                                gpointer      right)
+gtk_flatten_list_model_augment (GtkRbTree *flatten,
+                                gpointer   _aug,
+                                gpointer   _node,
+                                gpointer   left,
+                                gpointer   right)
 {
-  FlattenNode *node= _node;
+  FlattenNode *node = _node;
   FlattenAugment *aug = _aug;
 
   aug->n_items = g_list_model_get_n_items (node->model);
@@ -265,13 +265,13 @@ gtk_flatten_list_model_augment (GtkCssRbTree *flatten,
 
   if (left)
     {
-      FlattenAugment *left_aug = gtk_css_rb_tree_get_augment (flatten, left);
+      FlattenAugment *left_aug = gtk_rb_tree_get_augment (flatten, left);
       aug->n_items += left_aug->n_items;
       aug->n_models += left_aug->n_models;
     }
   if (right)
     {
-      FlattenAugment *right_aug = gtk_css_rb_tree_get_augment (flatten, right);
+      FlattenAugment *right_aug = gtk_rb_tree_get_augment (flatten, right);
       aug->n_items += right_aug->n_items;
       aug->n_models += right_aug->n_models;
     }
@@ -289,7 +289,7 @@ gtk_flatten_list_model_add_items (GtkFlattenListModel *self,
   added = 0;
   for (i = 0; i < n; i++)
     {
-      node = gtk_css_rb_tree_insert_before (self->items, after);
+      node = gtk_rb_tree_insert_before (self->items, after);
       node->model = g_list_model_get_item (self->model, position + i);
       g_warn_if_fail (g_type_is_a (g_list_model_get_item_type (node->model), self->item_type));
       g_signal_connect (node->model,
@@ -366,9 +366,9 @@ gtk_flatten_list_model_model_items_changed_cb (GListModel          *model,
   real_removed = 0;
   for (i = 0; i < removed; i++)
     {
-      FlattenNode *next = gtk_css_rb_tree_get_next (self->items, node);
+      FlattenNode *next = gtk_rb_tree_get_next (self->items, node);
       real_removed += g_list_model_get_n_items (node->model);
-      gtk_css_rb_tree_remove (self->items, node);
+      gtk_rb_tree_remove (self->items, node);
       node = next;
     }
 
@@ -385,7 +385,7 @@ gtk_flatten_list_clear_model (GtkFlattenListModel *self)
     {
       g_signal_handlers_disconnect_by_func (self->model, gtk_flatten_list_model_model_items_changed_cb, self);
       g_clear_object (&self->model);
-      g_clear_pointer (&self->items, gtk_css_rb_tree_unref);
+      g_clear_pointer (&self->items, gtk_rb_tree_unref);
     }
 }
 
@@ -397,7 +397,7 @@ gtk_flatten_list_model_dispose (GObject *object)
   gtk_flatten_list_clear_model (self);
 
   G_OBJECT_CLASS (gtk_flatten_list_model_parent_class)->dispose (object);
-};
+}
 
 static void
 gtk_flatten_list_model_class_init (GtkFlattenListModelClass *class)
@@ -501,11 +501,11 @@ gtk_flatten_list_model_set_model (GtkFlattenListModel *self,
     {
       g_object_ref (model);
       g_signal_connect (model, "items-changed", G_CALLBACK (gtk_flatten_list_model_model_items_changed_cb), self);
-      self->items = gtk_css_rb_tree_new (FlattenNode,
-                                         FlattenAugment,
-                                         gtk_flatten_list_model_augment,
-                                         gtk_flatten_list_model_clear_node,
-                                         NULL);
+      self->items = gtk_rb_tree_new (FlattenNode,
+                                     FlattenAugment,
+                                     gtk_flatten_list_model_augment,
+                                     gtk_flatten_list_model_clear_node,
+                                     NULL);
 
       added = gtk_flatten_list_model_add_items (self, NULL, 0, g_list_model_get_n_items (model));
     }
index 6f5e331d80738ba75025d6800d5fb3d464ce6627..9be8aa792247da50493825e52e49a525be25dbbd 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "gtkmaplistmodel.h"
 
-#include "gtkcssrbtreeprivate.h"
+#include "gtkrbtreeprivate.h"
 #include "gtkintl.h"
 #include "gtkprivate.h"
 
@@ -73,7 +73,7 @@ struct _GtkMapListModel
   gpointer user_data;
   GDestroyNotify user_destroy;
 
-  GtkCssRbTree *items; /* NULL if map_func == NULL */
+  GtkRbTree *items; /* NULL if map_func == NULL */
 };
 
 struct _GtkMapListModelClass
@@ -84,21 +84,21 @@ struct _GtkMapListModelClass
 static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
 
 static MapNode *
-gtk_map_list_model_get_nth (GtkCssRbTree *tree,
-                            guint         position,
-                            guint        *out_start_pos)
+gtk_map_list_model_get_nth (GtkRbTree *tree,
+                            guint      position,
+                            guint     *out_start_pos)
 {
   MapNode *node, *tmp;
   guint start_pos = position;
 
-  node = gtk_css_rb_tree_get_root (tree);
+  node = gtk_rb_tree_get_root (tree);
 
   while (node)
     {
-      tmp = gtk_css_rb_tree_get_left (tree, node);
+      tmp = gtk_rb_tree_get_left (tree, node);
       if (tmp)
         {
-          MapAugment *aug = gtk_css_rb_tree_get_augment (tree, tmp);
+          MapAugment *aug = gtk_rb_tree_get_augment (tree, tmp);
           if (position < aug->n_items)
             {
               node = tmp;
@@ -114,7 +114,7 @@ gtk_map_list_model_get_nth (GtkCssRbTree *tree,
         }
       position -= node->n_items;
 
-      node = gtk_css_rb_tree_get_right (tree, node);
+      node = gtk_rb_tree_get_right (tree, node);
     }
 
   if (out_start_pos)
@@ -165,18 +165,18 @@ gtk_map_list_model_get_item (GListModel *list,
 
   if (offset != position)
     {
-      MapNode *before = gtk_css_rb_tree_insert_before (self->items, node);
+      MapNode *before = gtk_rb_tree_insert_before (self->items, node);
       before->n_items = position - offset;
       node->n_items -= before->n_items;
-      gtk_css_rb_tree_mark_dirty (self->items, node);
+      gtk_rb_tree_mark_dirty (self->items, node);
     }
 
   if (node->n_items > 1)
     {
-      MapNode *after = gtk_css_rb_tree_insert_after (self->items, node);
+      MapNode *after = gtk_rb_tree_insert_after (self->items, node);
       after->n_items = node->n_items - 1;
       node->n_items = 1;
-      gtk_css_rb_tree_mark_dirty (self->items, node);
+      gtk_rb_tree_mark_dirty (self->items, node);
     }
 
   node->item = self->map_func (g_list_model_get_item (self->model, position), self->user_data);
@@ -225,9 +225,9 @@ gtk_map_list_model_items_changed_cb (GListModel      *model,
       end = start + node->n_items;
       if (start == position && end <= position + removed)
         {
-          MapNode *next = gtk_css_rb_tree_get_next (self->items, node);
+          MapNode *next = gtk_rb_tree_get_next (self->items, node);
           removed -= node->n_items;
-          gtk_css_rb_tree_remove (self->items, node);
+          gtk_rb_tree_remove (self->items, node);
           node = next;
         }
       else
@@ -236,16 +236,16 @@ gtk_map_list_model_items_changed_cb (GListModel      *model,
             {
               node->n_items -= removed;
               removed = 0;
-              gtk_css_rb_tree_mark_dirty (self->items, node);
+              gtk_rb_tree_mark_dirty (self->items, node);
             }
           else if (start < position)
             {
               guint overlap = node->n_items - (position - start);
               node->n_items -= overlap;
-              gtk_css_rb_tree_mark_dirty (self->items, node);
+              gtk_rb_tree_mark_dirty (self->items, node);
               removed -= overlap;
               start = position;
-              node = gtk_css_rb_tree_get_next (self->items, node);
+              node = gtk_rb_tree_get_next (self->items, node);
             }
         }
     }
@@ -253,12 +253,12 @@ gtk_map_list_model_items_changed_cb (GListModel      *model,
   if (added)
     {
       if (node == NULL)
-        node = gtk_css_rb_tree_insert_before (self->items, NULL);
+        node = gtk_rb_tree_insert_before (self->items, NULL);
       else if (node->item)
-        node = gtk_css_rb_tree_insert_after (self->items, node);
+        node = gtk_rb_tree_insert_after (self->items, node);
 
       node->n_items += added;
-      gtk_css_rb_tree_mark_dirty (self->items, node);
+      gtk_rb_tree_mark_dirty (self->items, node);
     }
 
   g_list_model_items_changed (G_LIST_MODEL (self), position, removed, added);
@@ -337,10 +337,10 @@ gtk_map_list_model_dispose (GObject *object)
   self->map_func = NULL;
   self->user_data = NULL;
   self->user_destroy = NULL;
-  g_clear_pointer (&self->items, gtk_css_rb_tree_unref);
+  g_clear_pointer (&self->items, gtk_rb_tree_unref);
 
   G_OBJECT_CLASS (gtk_map_list_model_parent_class)->dispose (object);
-};
+}
 
 static void
 gtk_map_list_model_class_init (GtkMapListModelClass *class)
@@ -397,25 +397,25 @@ gtk_map_list_model_init (GtkMapListModel *self)
 
 
 static void
-gtk_map_list_model_augment (GtkCssRbTree *map,
-                            gpointer      _aug,
-                            gpointer      _node,
-                            gpointer      left,
-                            gpointer      right)
+gtk_map_list_model_augment (GtkRbTree *map,
+                            gpointer   _aug,
+                            gpointer   _node,
+                            gpointer   left,
+                            gpointer   right)
 {
-  MapNode *node= _node;
+  MapNode *node = _node;
   MapAugment *aug = _aug;
 
   aug->n_items = node->n_items;
 
   if (left)
     {
-      MapAugment *left_aug = gtk_css_rb_tree_get_augment (map, left);
+      MapAugment *left_aug = gtk_rb_tree_get_augment (map, left);
       aug->n_items += left_aug->n_items;
     }
   if (right)
     {
-      MapAugment *right_aug = gtk_css_rb_tree_get_augment (map, right);
+      MapAugment *right_aug = gtk_rb_tree_get_augment (map, right);
       aug->n_items += right_aug->n_items;
     }
 }
@@ -473,28 +473,28 @@ gtk_map_list_model_init_items (GtkMapListModel *self)
 
       if (self->items)
         {
-          gtk_css_rb_tree_remove_all (self->items);
+          gtk_rb_tree_remove_all (self->items);
         }
       else
         {
-          self->items = gtk_css_rb_tree_new (MapNode,
-                                             MapAugment, 
-                                             gtk_map_list_model_augment,
-                                             gtk_map_list_model_clear_node,
-                                             NULL);
+          self->items = gtk_rb_tree_new (MapNode,
+                                         MapAugment,
+                                         gtk_map_list_model_augment,
+                                         gtk_map_list_model_clear_node,
+                                         NULL);
         }
 
       n_items = g_list_model_get_n_items (self->model);
       if (n_items)
         {
-          MapNode *node = gtk_css_rb_tree_insert_before (self->items, NULL);
+          MapNode *node = gtk_rb_tree_insert_before (self->items, NULL);
           node->n_items = g_list_model_get_n_items (self->model);
-          gtk_css_rb_tree_mark_dirty (self->items, node);
+          gtk_rb_tree_mark_dirty (self->items, node);
         }
     }
   else
     {
-      g_clear_pointer (&self->items, gtk_css_rb_tree_unref);
+      g_clear_pointer (&self->items, gtk_rb_tree_unref);
     }
 }
 
diff --git a/gtk/gtkrbtree.c b/gtk/gtkrbtree.c
new file mode 100644 (file)
index 0000000..a7576ff
--- /dev/null
@@ -0,0 +1,761 @@
+/* gtkrbtree.c
+ * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "gtkrbtreeprivate.h"
+
+#include "gtkdebug.h"
+
+typedef struct _GtkRbNode GtkRbNode;
+
+struct _GtkRbTree
+{
+  guint ref_count;
+
+  gsize element_size;
+  gsize augment_size;
+  GtkRbTreeAugmentFunc augment_func;
+  GDestroyNotify clear_func;
+  GDestroyNotify clear_augment_func;
+
+  GtkRbNode *root;
+};
+
+struct _GtkRbNode
+{
+  guint red :1;
+  guint dirty :1;
+
+  GtkRbNode *left;
+  GtkRbNode *right;
+  GtkRbNode *parent;
+};
+
+#define NODE_FROM_POINTER(ptr) ((GtkRbNode *) ((ptr) ? (((guchar *) (ptr)) - sizeof (GtkRbNode)) : NULL))
+#define NODE_TO_POINTER(node) ((gpointer) ((node) ? (((guchar *) (node)) + sizeof (GtkRbNode)) : NULL))
+#define NODE_TO_AUG_POINTER(tree, node) ((gpointer) ((node) ? (((guchar *) (node)) + sizeof (GtkRbNode) + (tree)->element_size) : NULL))
+
+static inline gsize
+gtk_rb_node_get_size (GtkRbTree *tree)
+{
+  return sizeof (GtkRbNode) + tree->element_size + tree->augment_size;
+}
+
+static GtkRbNode *
+gtk_rb_node_new (GtkRbTree *tree)
+{
+  GtkRbNode *result;
+
+  result = g_slice_alloc0 (gtk_rb_node_get_size (tree));
+
+  result->red = TRUE;
+  result->dirty = TRUE;
+
+  return result;
+}
+
+static void
+gtk_rb_node_free (GtkRbTree *tree,
+                  GtkRbNode *node)
+{
+  if (tree->clear_func)
+    tree->clear_func (NODE_TO_POINTER (node));
+  if (tree->clear_augment_func)
+    tree->clear_augment_func (NODE_TO_AUG_POINTER (tree, node));
+
+  g_slice_free1 (gtk_rb_node_get_size (tree), node);
+}
+
+static void
+gtk_rb_node_free_deep (GtkRbTree *tree,
+                       GtkRbNode *node)
+{
+  GtkRbNode *right = node->right;
+
+  if (node->left)
+    gtk_rb_node_free_deep (tree, node->left);
+
+  gtk_rb_node_free (tree, node);
+
+  if (right)
+    gtk_rb_node_free_deep (tree, right);
+}
+
+static void
+gtk_rb_node_mark_dirty (GtkRbNode *node,
+                        gboolean   mark_parent)
+{
+  if (node->dirty)
+    return;
+  
+  node->dirty = TRUE;
+
+  if (mark_parent && node->parent)
+    gtk_rb_node_mark_dirty (node->parent, TRUE);
+}
+
+static void
+gtk_rb_node_clean (GtkRbTree *tree,
+                   GtkRbNode *node)
+{
+  if (!node->dirty)
+    return;
+
+  node->dirty = FALSE;
+  if (tree->augment_func)
+    tree->augment_func (tree,
+                        NODE_TO_AUG_POINTER (tree, node),
+                        NODE_TO_POINTER (node),
+                        NODE_TO_POINTER (node->left),
+                        NODE_TO_POINTER (node->right));
+}
+
+static GtkRbNode *
+gtk_rb_node_get_first (GtkRbNode *node)
+{
+  while (node->left)
+    node = node->left;
+
+  return node;
+}
+
+static GtkRbNode *
+gtk_rb_node_get_last (GtkRbNode *node)
+{
+  while (node->right)
+    node = node->right;
+
+  return node;
+}
+
+static GtkRbNode *
+gtk_rb_node_get_previous (GtkRbNode *node)
+{
+  GtkRbNode *parent;
+
+  if (node->left)
+    return gtk_rb_node_get_last (node->left);
+
+  for (parent = node->parent; parent != NULL; parent = node->parent)
+    {
+      if (parent->right == node)
+        return parent;
+
+      node = parent;
+    }
+
+  return NULL;
+}
+
+static GtkRbNode *
+gtk_rb_node_get_next (GtkRbNode *node)
+{
+  GtkRbNode *parent;
+
+  if (node->right)
+    return gtk_rb_node_get_first (node->right);
+
+  for (parent = node->parent; parent != NULL; parent = node->parent)
+    {
+      if (parent->left == node)
+        return parent;
+
+      node = parent;
+    }
+
+  return NULL;
+}
+
+static void
+gtk_rb_node_rotate_left (GtkRbTree *tree,
+                         GtkRbNode *node)
+{
+  GtkRbNode *right;
+
+  right = node->right;
+
+  node->right = right->left;
+  if (right->left)
+    right->left->parent = node;
+
+  right->parent = node->parent;
+  if (node->parent)
+    {
+      if (node == node->parent->left)
+       node->parent->left = right;
+      else
+       node->parent->right = right;
+    }
+  else
+    {
+      tree->root = right;
+    }
+
+  right->left = node;
+  node->parent = right;
+
+  gtk_rb_node_mark_dirty (node, FALSE);
+  gtk_rb_node_mark_dirty (right, FALSE);
+}
+
+static void
+gtk_rb_node_rotate_right (GtkRbTree *tree,
+                          GtkRbNode *node)
+{
+  GtkRbNode *left;
+
+  left = node->left;
+
+  node->left = left->right;
+  if (left->right)
+    left->right->parent = node;
+
+  left->parent = node->parent;
+  if (node->parent)
+    {
+      if (node == node->parent->right)
+       node->parent->right = left;
+      else
+       node->parent->left = left;
+    }
+  else
+    {
+      tree->root = left;
+    }
+
+  /* link node and left */
+  left->right = node;
+  node->parent = left;
+
+  gtk_rb_node_mark_dirty (node, FALSE);
+  gtk_rb_node_mark_dirty (left, FALSE);
+}
+
+static gboolean
+is_red (GtkRbNode *node_or_null)
+{
+  if (node_or_null == NULL)
+    return FALSE;
+  else
+    return node_or_null->red;
+}
+
+static inline gboolean
+is_black (GtkRbNode *node_or_null)
+{
+  return !is_red (node_or_null);
+}
+
+static void
+set_black (GtkRbNode *node_or_null)
+{
+  if (node_or_null == NULL)
+    return;
+
+  node_or_null->red = FALSE;
+}
+
+static void
+set_red (GtkRbNode *node_or_null)
+{
+  if (node_or_null == NULL)
+    return;
+
+  node_or_null->red = TRUE;
+}
+
+static void
+gtk_rb_tree_insert_fixup (GtkRbTree *tree,
+                          GtkRbNode *node)
+{
+
+  /* check Red-Black properties */
+  while (node->parent && is_red (node->parent))
+    {
+      /* we have a violation */
+      g_assert (node->parent->parent);
+
+      if (node->parent == node->parent->parent->left)
+       {
+         GtkRbNode *uncle = node->parent->parent->right;
+
+         if (is_red (uncle))
+           {
+             /* uncle is red */
+             set_black (node->parent);
+              set_black (uncle);
+              set_red (node->parent->parent);
+             node = node->parent->parent;
+           }
+         else
+           {
+             /* uncle is black */
+             if (node == node->parent->right)
+               {
+                 /* make node a left child */
+                 node = node->parent;
+                 gtk_rb_node_rotate_left (tree, node);
+               }
+             /* recolor and rotate */
+              set_black (node->parent);
+              set_red (node->parent->parent);
+             gtk_rb_node_rotate_right (tree, node->parent->parent);
+           }
+       }
+      else
+       {
+         /* mirror image of above code */
+         GtkRbNode *uncle = node->parent->parent->left;
+
+         if (is_red (uncle))
+           {
+             /* uncle is red */
+              set_black (node->parent);
+              set_black (uncle);
+              set_red (node->parent->parent);
+             node = node->parent->parent;
+           }
+         else
+           {
+              /* uncle is black */
+             if (node == node->parent->left)
+               {
+                 node = node->parent;
+                 gtk_rb_node_rotate_right (tree, node);
+               }
+             set_black (node->parent);
+             set_red (node->parent->parent);
+             gtk_rb_node_rotate_left (tree, node->parent->parent);
+           }
+       }
+    }
+
+  set_black (tree->root);
+}
+
+static void
+gtk_rb_tree_remove_node_fixup (GtkRbTree *tree,
+                               GtkRbNode *node,
+                               GtkRbNode *parent)
+{
+  while (node != tree->root && is_black (node))
+    {
+      if (node == parent->left)
+       {
+         GtkRbNode *w = parent->right;
+
+         if (is_red (w))
+           {
+             set_black (w);
+              set_red (parent);
+             gtk_rb_node_rotate_left (tree, parent);
+             w = parent->right;
+           }
+         if (is_black (w->left) && is_black (w->right))
+           {
+             set_red (w);
+             node = parent;
+           }
+         else
+           {
+             if (is_black (w->right))
+               {
+                 set_black (w->left);
+                 set_red (w);
+                 gtk_rb_node_rotate_right (tree, w);
+                 w = parent->right;
+               }
+             w->red = parent->red;
+             set_black (parent);
+              set_black (w->right);
+             gtk_rb_node_rotate_left (tree, parent);
+             node = tree->root;
+           }
+       }
+      else
+       {
+         GtkRbNode *w = parent->left;
+         if (is_red (w))
+           {
+             set_black (w);
+             set_red (parent);
+             gtk_rb_node_rotate_right (tree, parent);
+             w = parent->left;
+           }
+         if (is_black (w->right) && is_black (w->left))
+           {
+             set_red (w);
+             node = parent;
+           }
+         else
+           {
+             if (is_black (w->left))
+               {
+                 set_black (w->right);
+                 set_red (w);
+                 gtk_rb_node_rotate_left (tree, w);
+                 w = parent->left;
+               }
+             w->red = parent->red;
+             set_black (parent);
+             set_black (w->left);
+             gtk_rb_node_rotate_right (tree, parent);
+             node = tree->root;
+           }
+       }
+
+      parent = node->parent;
+    }
+
+  set_black (node);
+}
+
+GtkRbTree *
+gtk_rb_tree_new_for_size (gsize                element_size,
+                          gsize                augment_size,
+                          GtkRbTreeAugmentFunc augment_func,
+                          GDestroyNotify       clear_func,
+                          GDestroyNotify       clear_augment_func)
+{
+  GtkRbTree *tree;
+
+  tree = g_slice_new0 (GtkRbTree);
+  tree->ref_count = 1;
+
+  tree->element_size = element_size;
+  tree->augment_size = augment_size;
+  tree->augment_func = augment_func;
+  tree->clear_func = clear_func;
+  tree->clear_augment_func = clear_augment_func;
+
+  return tree;
+}
+
+GtkRbTree *
+gtk_rb_tree_ref (GtkRbTree *tree)
+{
+  tree->ref_count++;
+
+  return tree;
+}
+
+void
+gtk_rb_tree_unref (GtkRbTree *tree)
+{
+  tree->ref_count--;
+  if (tree->ref_count > 0)
+    return;
+
+  if (tree->root)
+    gtk_rb_node_free_deep (tree, tree->root);
+    
+  g_slice_free (GtkRbTree, tree);
+}
+
+gpointer
+gtk_rb_tree_get_first (GtkRbTree *tree)
+{
+  if (tree->root == NULL)
+    return NULL;
+
+  return NODE_TO_POINTER (gtk_rb_node_get_first (tree->root));
+}
+
+gpointer
+gtk_rb_tree_get_last (GtkRbTree *tree)
+{
+  if (tree->root == NULL)
+    return NULL;
+
+  return NODE_TO_POINTER (gtk_rb_node_get_last (tree->root));
+}
+
+gpointer
+gtk_rb_tree_get_previous (GtkRbTree *tree,
+                          gpointer   node)
+{
+  return NODE_TO_POINTER (gtk_rb_node_get_previous (NODE_FROM_POINTER (node)));
+}
+
+gpointer
+gtk_rb_tree_get_next (GtkRbTree *tree,
+                      gpointer   node)
+{
+  return NODE_TO_POINTER (gtk_rb_node_get_next (NODE_FROM_POINTER (node)));
+}
+
+gpointer
+gtk_rb_tree_get_root (GtkRbTree *tree)
+{
+  return NODE_TO_POINTER (tree->root);
+}
+
+gpointer
+gtk_rb_tree_get_parent (GtkRbTree *tree,
+                        gpointer   node)
+{
+  return NODE_TO_POINTER (NODE_FROM_POINTER (node)->parent);
+}
+
+gpointer
+gtk_rb_tree_get_left (GtkRbTree *tree,
+                      gpointer   node)
+{
+  return NODE_TO_POINTER (NODE_FROM_POINTER (node)->left);
+}
+
+gpointer
+gtk_rb_tree_get_right (GtkRbTree *tree,
+                       gpointer   node)
+{
+  return NODE_TO_POINTER (NODE_FROM_POINTER (node)->right);
+}
+
+gpointer
+gtk_rb_tree_get_augment (GtkRbTree *tree,
+                         gpointer   node)
+{
+  GtkRbNode *rbnode = NODE_FROM_POINTER (node);
+
+  gtk_rb_node_clean (tree, rbnode);
+
+  return NODE_TO_AUG_POINTER (tree, rbnode);
+}
+
+void
+gtk_rb_tree_mark_dirty (GtkRbTree *tree,
+                        gpointer   node)
+{
+  gtk_rb_node_mark_dirty (NODE_FROM_POINTER (node), TRUE);
+}
+
+gpointer
+gtk_rb_tree_insert_before (GtkRbTree *tree,
+                           gpointer   node)
+{
+  GtkRbNode *result;
+
+  /* setup new node */
+  result = gtk_rb_node_new (tree);
+
+  if (tree->root == NULL)
+    {
+      g_assert (node == NULL);
+      tree->root = result;
+    }
+  else if (node == NULL)
+    {
+      return gtk_rb_tree_insert_after (tree, gtk_rb_tree_get_last (tree));
+    }
+  else
+    {
+      GtkRbNode *current = NODE_FROM_POINTER (node);
+
+      if (current->left)
+        {
+          current = gtk_rb_node_get_last (current->left);
+          current->right = result;
+        }
+      else
+        {
+          current->left = result;
+        }
+      result->parent = current;
+      gtk_rb_node_mark_dirty (current, TRUE);
+    }
+
+  gtk_rb_tree_insert_fixup (tree, result);
+
+  return NODE_TO_POINTER (result);
+}
+
+gpointer
+gtk_rb_tree_insert_after (GtkRbTree *tree,
+                          gpointer   node)
+{
+  GtkRbNode *result;
+
+  /* setup new node */
+  result = gtk_rb_node_new (tree);
+
+  if (tree->root == NULL)
+    {
+      g_assert (node == NULL);
+      tree->root = result;
+    }
+  else if (node == NULL)
+    {
+      return gtk_rb_tree_insert_before (tree, gtk_rb_tree_get_first (tree));
+    }
+  else
+    {
+      GtkRbNode *current = NODE_FROM_POINTER (node);
+
+      if (current->right)
+        {
+          current = gtk_rb_node_get_first (current->right);
+          current->left = result;
+        }
+      else
+        {
+          current->right = result;
+        }
+      result->parent = current;
+      gtk_rb_node_mark_dirty (current, TRUE);
+    }
+
+  gtk_rb_tree_insert_fixup (tree, result);
+
+  return NODE_TO_POINTER (result);
+}
+
+void
+gtk_rb_tree_remove (GtkRbTree *tree,
+                    gpointer   node)
+{
+  GtkRbNode *x, *y, *real_node;
+  
+  real_node = NODE_FROM_POINTER (node);
+  y = real_node;
+  if (y->left && y->right)
+    {
+      y = y->right;
+
+      while (y->left)
+       y = y->left;
+    }
+
+  /* x is y's only child, or nil */
+  if (y->left)
+    x = y->left;
+  else
+    x = y->right;
+
+  /* remove y from the parent chain */
+  if (x != NULL)
+    x->parent = y->parent;
+  if (y->parent)
+    {
+      if (y == y->parent->left)
+       y->parent->left = x;
+      else
+       y->parent->right = x;
+      gtk_rb_node_mark_dirty (y->parent, TRUE);
+    }
+  else
+    {
+      tree->root = x;
+    }
+
+  /* We need to clean up the validity of the tree.
+   */
+  if (is_black (y))
+    gtk_rb_tree_remove_node_fixup (tree, x, y->parent);
+
+  if (y != real_node)
+    {
+      /* Move the node over */
+      if (is_red (real_node) != is_red (y))
+       y->red = !y->red;
+
+      y->left = real_node->left;
+      if (y->left)
+        y->left->parent = y;
+      y->right = real_node->right;
+      if (y->right)
+        y->right->parent = y;
+      y->parent = real_node->parent;
+      if (y->parent)
+        {
+          if (y->parent->left == real_node)
+            y->parent->left = y;
+          else
+            y->parent->right = y;
+          gtk_rb_node_mark_dirty (y->parent, TRUE);
+        }
+      else
+        {
+          tree->root = y;
+        }
+      gtk_rb_node_mark_dirty (y, TRUE);
+    }
+
+  gtk_rb_node_free (tree, real_node);
+}
+
+void
+gtk_rb_tree_remove_all (GtkRbTree *tree)
+{
+  if (tree->root)
+    gtk_rb_node_free_deep (tree, tree->root);
+
+  tree->root = NULL;
+}
+
+gpointer
+gtk_rb_tree_find (GtkRbTree           *tree,
+                  gpointer            *out_before,
+                  gpointer            *out_after,
+                  GtkRbTreeFindFunc    find_func,
+                  gpointer             user_data)
+{
+  GtkRbNode *node, *before = NULL, *after = NULL;
+  int cmp;
+
+  if (tree->root == NULL)
+    {
+      if (out_before)
+        *out_before = NULL;
+      if (out_after)
+        *out_after = NULL;
+
+      return NULL;
+    }
+
+  node = tree->root;
+  for (cmp = find_func (tree, NODE_TO_POINTER (node), user_data);
+       cmp != 0;
+       cmp = find_func (tree, NODE_TO_POINTER (node), user_data))
+    {
+      if (cmp < 0)
+        {
+          before = node;
+          node = node->right;
+        }
+      else /* cmp > 0 */
+        {
+          after = node;
+          node = node->left;
+        }
+      if (node == NULL)
+        {
+          if (out_before)
+            *out_before = NODE_TO_POINTER (before);
+          if (out_after)
+            *out_after = NODE_TO_POINTER (after);
+          return NULL;;
+        }
+    }
+
+  if (out_before)
+    *out_before = NODE_TO_POINTER (gtk_rb_node_get_previous (node));
+  if (out_after)
+    *out_after = NODE_TO_POINTER (gtk_rb_node_get_next (node));
+
+  return NODE_TO_POINTER (node);
+}
diff --git a/gtk/gtkrbtreeprivate.h b/gtk/gtkrbtreeprivate.h
new file mode 100644 (file)
index 0000000..b73c807
--- /dev/null
@@ -0,0 +1,89 @@
+/* gtkrbtree.h
+ * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* A Red-Black Tree implementation used specifically by GtkTreeView.
+ */
+#ifndef __GTK_RB_TREE_H__
+#define __GTK_RB_TREE_H__
+
+#include <glib.h>
+
+
+G_BEGIN_DECLS
+
+
+typedef struct _GtkRbTree GtkRbTree;
+
+typedef void            (* GtkRbTreeAugmentFunc)        (GtkRbTree               *tree,
+                                                         gpointer                 node_augment,
+                                                         gpointer                 node,
+                                                         gpointer                 left,
+                                                         gpointer                 right);
+typedef int             (* GtkRbTreeFindFunc)           (GtkRbTree               *tree,
+                                                         gpointer                 node,
+                                                         gpointer                 user_data);
+
+GtkRbTree *          gtk_rb_tree_new_for_size           (gsize                    element_size,
+                                                         gsize                    augment_size,
+                                                         GtkRbTreeAugmentFunc     augment_func,
+                                                         GDestroyNotify           clear_func,
+                                                         GDestroyNotify           clear_augment_func);
+#define gtk_rb_tree_new(type, augment_type, augment_func, clear_func, clear_augment_func) \
+  gtk_rb_tree_new_for_size (sizeof (type), sizeof (augment_type), (augment_func), (clear_func), (clear_augment_func))
+
+GtkRbTree *          gtk_rb_tree_ref                    (GtkRbTree               *tree);
+void                 gtk_rb_tree_unref                  (GtkRbTree               *tree);
+
+gpointer             gtk_rb_tree_get_first              (GtkRbTree               *tree);
+gpointer             gtk_rb_tree_get_last               (GtkRbTree               *tree);
+gpointer             gtk_rb_tree_get_previous           (GtkRbTree               *tree,
+                                                         gpointer                 node);
+gpointer             gtk_rb_tree_get_next               (GtkRbTree               *tree,
+                                                         gpointer                 node);
+
+gpointer             gtk_rb_tree_get_root               (GtkRbTree               *tree);
+gpointer             gtk_rb_tree_get_parent             (GtkRbTree               *tree,
+                                                         gpointer                 node);
+gpointer             gtk_rb_tree_get_left               (GtkRbTree               *tree,
+                                                         gpointer                 node);
+gpointer             gtk_rb_tree_get_right              (GtkRbTree               *tree,
+                                                         gpointer                 node);
+gpointer             gtk_rb_tree_get_augment            (GtkRbTree               *tree,
+                                                         gpointer                 node);
+
+void                 gtk_rb_tree_mark_dirty             (GtkRbTree               *tree,
+                                                         gpointer                 node);
+
+gpointer             gtk_rb_tree_insert_before          (GtkRbTree               *tree,
+                                                         gpointer                 node);
+gpointer             gtk_rb_tree_insert_after           (GtkRbTree               *tree,
+                                                         gpointer                 node);
+void                 gtk_rb_tree_remove                 (GtkRbTree               *tree,
+                                                         gpointer                 node);
+void                 gtk_rb_tree_remove_all             (GtkRbTree               *tree);
+
+gpointer             gtk_rb_tree_find                   (GtkRbTree               *tree,
+                                                         gpointer                *out_before,
+                                                         gpointer                *out_after,
+                                                         GtkRbTreeFindFunc        find_func,
+                                                         gpointer                 user_data);
+
+
+G_END_DECLS
+
+
+#endif /* __GTK_RB_TREE_H__ */
index 5144462e5c3418ceb35ab1ec6c31bc89dc76616c..712e46ca68ecaa56f1b045e0eb28ea939d5d2564 100644 (file)
@@ -21,7 +21,6 @@
 
 #include "gtkslicelistmodel.h"
 
-#include "gtkcssrbtreeprivate.h"
 #include "gtkintl.h"
 #include "gtkprivate.h"
 
index 186a25b967b7477955d7e59263702c026ba0728b..af609e61ce8f01fbf026cb2d23a9fbd6c2809e5a 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "gtktreelistmodel.h"
 
-#include "gtkcssrbtreeprivate.h"
+#include "gtkrbtreeprivate.h"
 #include "gtkintl.h"
 #include "gtkprivate.h"
 
@@ -50,7 +50,7 @@ struct _TreeNode
 {
   GListModel *model;
   GtkTreeListRow *row;
-  GtkCssRbTree *children;
+  GtkRbTree *children;
   union {
     TreeNode *parent;
     GtkTreeListModel *list;
@@ -112,19 +112,19 @@ static TreeNode *
 tree_node_get_nth_child (TreeNode *node,
                          guint     position)
 {
-  GtkCssRbTree *tree;
+  GtkRbTree *tree;
   TreeNode *child, *tmp;
   TreeAugment *aug;
 
   tree = node->children;
-  child = gtk_css_rb_tree_get_root (tree);
+  child = gtk_rb_tree_get_root (tree);
 
   while (child)
     {
-      tmp = gtk_css_rb_tree_get_left (tree, child);
+      tmp = gtk_rb_tree_get_left (tree, child);
       if (tmp)
         {
-          aug = gtk_css_rb_tree_get_augment (tree, tmp);
+          aug = gtk_rb_tree_get_augment (tree, tmp);
           if (position < aug->n_local)
             {
               child = tmp;
@@ -138,7 +138,7 @@ tree_node_get_nth_child (TreeNode *node,
 
       position--;
 
-      child = gtk_css_rb_tree_get_right (tree, child);
+      child = gtk_rb_tree_get_right (tree, child);
     }
 
   return NULL;
@@ -153,27 +153,27 @@ tree_node_get_n_children (TreeNode *node)
   if (node->children == NULL)
     return 0;
 
-  child_node = gtk_css_rb_tree_get_root (node->children);
+  child_node = gtk_rb_tree_get_root (node->children);
   if (child_node == NULL)
     return 0;
 
-  child_aug = gtk_css_rb_tree_get_augment (node->children, child_node);
+  child_aug = gtk_rb_tree_get_augment (node->children, child_node);
 
   return child_aug->n_items;
 }
 
 static guint
-tree_node_get_local_position (GtkCssRbTree *tree,
-                              TreeNode     *node)
+tree_node_get_local_position (GtkRbTree *tree,
+                              TreeNode  *node)
 {
   TreeNode *left, *parent;
   TreeAugment *left_aug;
   guint n;
   
-  left = gtk_css_rb_tree_get_left (tree, node);
+  left = gtk_rb_tree_get_left (tree, node);
   if (left)
     {
-      left_aug = gtk_css_rb_tree_get_augment (tree, left);
+      left_aug = gtk_rb_tree_get_augment (tree, left);
       n = left_aug->n_local;
     }
   else
@@ -181,11 +181,11 @@ tree_node_get_local_position (GtkCssRbTree *tree,
       n = 0;
     }
 
-  for (parent = gtk_css_rb_tree_get_parent (tree, node);
+  for (parent = gtk_rb_tree_get_parent (tree, node);
        parent;
-       parent = gtk_css_rb_tree_get_parent (tree, node))
+       parent = gtk_rb_tree_get_parent (tree, node))
     {
-      left = gtk_css_rb_tree_get_left (tree, parent);
+      left = gtk_rb_tree_get_left (tree, parent);
       if (left == node)
         {
           /* we are the left node, nothing changes */
@@ -196,7 +196,7 @@ tree_node_get_local_position (GtkCssRbTree *tree,
           n++;
           if (left)
             {
-              left_aug = gtk_css_rb_tree_get_augment (tree, left);
+              left_aug = gtk_rb_tree_get_augment (tree, left);
               n += left_aug->n_local;
             }
         }
@@ -209,7 +209,7 @@ tree_node_get_local_position (GtkCssRbTree *tree,
 static guint
 tree_node_get_position (TreeNode *node)
 {
-  GtkCssRbTree *tree;
+  GtkRbTree *tree;
   TreeNode *left, *parent;
   TreeAugment *left_aug;
   guint n;
@@ -220,18 +220,18 @@ tree_node_get_position (TreeNode *node)
     {
       tree = node->parent->children;
 
-      left = gtk_css_rb_tree_get_left (tree, node);
+      left = gtk_rb_tree_get_left (tree, node);
       if (left)
         {
-          left_aug = gtk_css_rb_tree_get_augment (tree, left);
+          left_aug = gtk_rb_tree_get_augment (tree, left);
           n += left_aug->n_items;
         }
 
-      for (parent = gtk_css_rb_tree_get_parent (tree, node);
+      for (parent = gtk_rb_tree_get_parent (tree, node);
            parent;
-           parent = gtk_css_rb_tree_get_parent (tree, node))
+           parent = gtk_rb_tree_get_parent (tree, node))
         {
-          left = gtk_css_rb_tree_get_left (tree, parent);
+          left = gtk_rb_tree_get_left (tree, parent);
           if (left == node)
             {
               /* we are the left node, nothing changes */
@@ -242,7 +242,7 @@ tree_node_get_position (TreeNode *node)
               n += 1 + tree_node_get_n_children (parent);
               if (left)
                 {
-                  left_aug = gtk_css_rb_tree_get_augment (tree, left);
+                  left_aug = gtk_rb_tree_get_augment (tree, left);
                   n += left_aug->n_items;
                 }
             }
@@ -262,7 +262,7 @@ tree_node_mark_dirty (TreeNode *node)
        !node->is_root;
        node = node->parent)
     {
-      gtk_css_rb_tree_mark_dirty (node->parent->children, node);
+      gtk_rb_tree_mark_dirty (node->parent->children, node);
     }
 }
 
@@ -270,7 +270,7 @@ static TreeNode *
 gtk_tree_list_model_get_nth (GtkTreeListModel *self,
                              guint             position)
 {
-  GtkCssRbTree *tree;
+  GtkRbTree *tree;
   TreeNode *node, *tmp;
   guint n_children;
 
@@ -279,14 +279,14 @@ gtk_tree_list_model_get_nth (GtkTreeListModel *self,
     return NULL;
 
   tree = self->root_node.children;
-  node = gtk_css_rb_tree_get_root (tree);
+  node = gtk_rb_tree_get_root (tree);
 
   while (TRUE)
     {
-      tmp = gtk_css_rb_tree_get_left (tree, node);
+      tmp = gtk_rb_tree_get_left (tree, node);
       if (tmp)
         {
-          TreeAugment *aug = gtk_css_rb_tree_get_augment (tree, tmp);
+          TreeAugment *aug = gtk_rb_tree_get_augment (tree, tmp);
           if (position < aug->n_items)
             {
               node = tmp;
@@ -304,12 +304,12 @@ gtk_tree_list_model_get_nth (GtkTreeListModel *self,
       if (position < n_children)
         {
           tree = node->children;
-          node = gtk_css_rb_tree_get_root (tree);
+          node = gtk_rb_tree_get_root (tree);
           continue;
         }
       position -= n_children;
 
-      node = gtk_css_rb_tree_get_right (tree, node);
+      node = gtk_rb_tree_get_right (tree, node);
     }
 
   g_return_val_if_reached (NULL);
@@ -406,8 +406,8 @@ gtk_tree_list_model_items_changed_cb (GListModel *model,
       for (i = 0; i < removed; i++)
         {
           tmp = child;
-          child = gtk_css_rb_tree_get_next (node->children, child);
-          gtk_css_rb_tree_remove (node->children, tmp);
+          child = gtk_rb_tree_get_next (node->children, child);
+          gtk_rb_tree_remove (node->children, tmp);
         }
     }
   else
@@ -418,7 +418,7 @@ gtk_tree_list_model_items_changed_cb (GListModel *model,
   tree_added = added;
   for (i = 0; i < added; i++)
     {
-      child = gtk_css_rb_tree_insert_before (node->children, child);
+      child = gtk_rb_tree_insert_before (node->children, child);
       child->parent = node;
     }
   if (self->autoexpand)
@@ -426,7 +426,7 @@ gtk_tree_list_model_items_changed_cb (GListModel *model,
       for (i = 0; i < added; i++)
         {
           tree_added += gtk_tree_list_model_expand_node (self, child);
-          child = gtk_css_rb_tree_get_next (node->children, child);
+          child = gtk_rb_tree_get_next (node->children, child);
         }
     }
 
@@ -456,15 +456,15 @@ gtk_tree_list_model_clear_node (gpointer data)
       g_object_unref (node->model);
     }
   if (node->children)
-    gtk_css_rb_tree_unref (node->children);
+    gtk_rb_tree_unref (node->children);
 }
 
 static void
-gtk_tree_list_model_augment (GtkCssRbTree *tree,
-                             gpointer      _aug,
-                             gpointer      _node,
-                             gpointer      left,
-                             gpointer      right)
+gtk_tree_list_model_augment (GtkRbTree *tree,
+                             gpointer   _aug,
+                             gpointer   _node,
+                             gpointer   left,
+                             gpointer   right)
 {
   TreeAugment *aug = _aug;
 
@@ -474,13 +474,13 @@ gtk_tree_list_model_augment (GtkCssRbTree *tree,
 
   if (left)
     {
-      TreeAugment *left_aug = gtk_css_rb_tree_get_augment (tree, left);
+      TreeAugment *left_aug = gtk_rb_tree_get_augment (tree, left);
       aug->n_items += left_aug->n_items;
       aug->n_local += left_aug->n_local;
     }
   if (right)
     {
-      TreeAugment *right_aug = gtk_css_rb_tree_get_augment (tree, right);
+      TreeAugment *right_aug = gtk_rb_tree_get_augment (tree, right);
       aug->n_items += right_aug->n_items;
       aug->n_local += right_aug->n_local;
     }
@@ -499,17 +499,17 @@ gtk_tree_list_model_init_node (GtkTreeListModel *list,
                     "items-changed",
                     G_CALLBACK (gtk_tree_list_model_items_changed_cb),
                     self);
-  self->children = gtk_css_rb_tree_new (TreeNode,
-                                        TreeAugment,
-                                        gtk_tree_list_model_augment,
-                                        gtk_tree_list_model_clear_node,
-                                        NULL);
+  self->children = gtk_rb_tree_new (TreeNode,
+                                    TreeAugment,
+                                    gtk_tree_list_model_augment,
+                                    gtk_tree_list_model_clear_node,
+                                    NULL);
 
   n = g_list_model_get_n_items (model);
   node = NULL;
   for (i = 0; i < n; i++)
     {
-      node = gtk_css_rb_tree_insert_after (self->children, node);
+      node = gtk_rb_tree_insert_after (self->children, node);
       node->parent = self;
       if (list->autoexpand)
         gtk_tree_list_model_expand_node (list, node);
@@ -561,7 +561,7 @@ gtk_tree_list_model_collapse_node (GtkTreeListModel *self,
 
   n_items = tree_node_get_n_children (node);
 
-  g_clear_pointer (&node->children, gtk_css_rb_tree_unref);
+  g_clear_pointer (&node->children, gtk_rb_tree_unref);
   g_clear_object (&node->model);
 
   tree_node_mark_dirty (node);
@@ -683,7 +683,7 @@ gtk_tree_list_model_finalize (GObject *object)
     self->user_destroy (self->user_data);
 
   G_OBJECT_CLASS (gtk_tree_list_model_parent_class)->finalize (object);
-};
+}
 
 static void
 gtk_tree_list_model_class_init (GtkTreeListModelClass *class)
@@ -1026,7 +1026,7 @@ gtk_tree_list_row_dispose (GObject *object)
     self->node->row = NULL;
 
   G_OBJECT_CLASS (gtk_tree_list_row_parent_class)->dispose (object);
-};
+}
 
 static void
 gtk_tree_list_row_class_init (GtkTreeListRowClass *class)
index e2eb7af3a57c47fb768761a4dafd979f6fbf83fd..e45b18bf8e8eae940a73b44730b8efb611569879 100644 (file)
@@ -79,7 +79,6 @@ gtk_private_sources = files([
   'gtkcssparser.c',
   'gtkcsspathnode.c',
   'gtkcsspositionvalue.c',
-  'gtkcssrbtree.c',
   'gtkcssrepeatvalue.c',
   'gtkcssrgbavalue.c',
   'gtkcssselector.c',
@@ -132,6 +131,7 @@ gtk_private_sources = files([
   'gtkprintutils.c',
   'gtkprivate.c',
   'gtkprogresstracker.c',
+  'gtkrbtree.c',
   'gtkquery.c',
   'gtkscaler.c',
   'gtksearchengine.c',
diff --git a/testsuite/gtk/cssrbtree-crash.c b/testsuite/gtk/cssrbtree-crash.c
deleted file mode 100644 (file)
index 3d10361..0000000
+++ /dev/null
@@ -1,286 +0,0 @@
-/* GtkRBTree tests.
- *
- * Copyright (C) 2011, Red Hat, Inc.
- * Authors: Benjamin Otte <otte@gnome.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <locale.h>
-
-#include <gtk/gtk.h>
-
-#include "gtk/gtkcssrbtreeprivate.h"
-
-typedef struct _Node Node;
-typedef struct _Aug Aug;
-
-struct _Node {
-  guint unused;
-};
-
-struct _Aug {
-  guint n_items;
-};
-
-static void
-augment (GtkCssRbTree *tree,
-         gpointer      _aug,
-         gpointer      _node,
-         gpointer      left,
-         gpointer      right)
-{
-  Aug *aug = _aug;
-  
-  aug->n_items = 1;
-
-  if (left)
-    {
-      Aug *left_aug = gtk_css_rb_tree_get_augment (tree, left);
-
-      aug->n_items += left_aug->n_items;
-    }
-
-  if (right)
-    {
-      Aug *right_aug = gtk_css_rb_tree_get_augment (tree, right);
-
-      aug->n_items += right_aug->n_items;
-    }
-}
-
-static Node *
-get (GtkCssRbTree *tree,
-     guint         pos)
-{
-  Node *node, *tmp;
-
-  node = gtk_css_rb_tree_get_root (tree);
-
-  while (node)
-    {
-      tmp = gtk_css_rb_tree_get_left (tree, node);
-      if (tmp)
-        {
-          Aug *aug = gtk_css_rb_tree_get_augment (tree, tmp);
-          if (pos < aug->n_items)
-            {
-              node = tmp;
-              continue;
-            }
-          pos -= aug->n_items;
-        }
-
-      if (pos < 1)
-        break;
-      pos--;
-
-      node = gtk_css_rb_tree_get_right (tree, node);
-    }
-
-  return node;
-}
-
-static void
-add (GtkCssRbTree *tree,
-     guint         pos)
-{
-  Node *node = get (tree, pos);
-
-  gtk_css_rb_tree_insert_before (tree, node);
-}
-
-static void
-delete (GtkCssRbTree *tree,
-        guint         pos)
-{
-  Node *node = get (tree, pos);
-
-  gtk_css_rb_tree_remove (tree, node);
-}
-
-static guint
-print_node (GtkCssRbTree *tree,
-            Node         *node,
-            guint         depth,
-            const char   *prefix,
-            guint         n)
-{
-  Node *child;
-
-  child = gtk_css_rb_tree_get_left (tree, node);
-  if (child)
-    n = print_node (tree, child, depth + 1, "/", n);
-  g_print ("%*s %u\n", 2 * depth, prefix, n);
-  n++;
-  child = gtk_css_rb_tree_get_right (tree, node);
-  if (child)
-    n = print_node (tree, child, depth + 1, "\\", n);
-
-  return n;
-}
-
-static void
-print (GtkCssRbTree *tree)
-{
-  print_node (tree, gtk_css_rb_tree_get_root (tree), 0, "", 0);
-}
-
-static void
-test_crash (void)
-{
-  GtkCssRbTree *tree;
-  guint i;
-
-  tree = gtk_css_rb_tree_new (Node, Aug, augment, NULL, NULL);
-
-  for (i = 0; i < 300; i++)
-    add (tree, i);
-  print (tree);
-  delete (tree, 144);
-  add (tree, 56);
-  delete (tree, 113);
-  delete (tree, 278);
-  delete (tree, 45);
-  delete (tree, 108);
-  delete (tree, 41);
-  add (tree, 56);
-  add (tree, 200);
-  delete (tree, 127);
-  delete (tree, 222);
-  add (tree, 80);
-  add (tree, 143);
-  add (tree, 216);
-  delete (tree, 177);
-  delete (tree, 193);
-  add (tree, 190);
-  delete (tree, 288);
-  add (tree, 45);
-  add (tree, 57);
-  add (tree, 211);
-  delete (tree, 103);
-  add (tree, 152);
-  delete (tree, 60);
-  add (tree, 185);
-  delete (tree, 167);
-  add (tree, 92);
-  delete (tree, 104);
-  delete (tree, 110);
-  delete (tree, 115);
-  add (tree, 32);
-  delete (tree, 44);
-  add (tree, 159);
-  add (tree, 271);
-  delete (tree, 35);
-  add (tree, 250);
-  delete (tree, 36);
-  add (tree, 284);
-  delete (tree, 82);
-  delete (tree, 248);
-  add (tree, 22);
-  delete (tree, 284);
-  add (tree, 88);
-  delete (tree, 182);
-  add (tree, 70);
-  add (tree, 55);
-  delete (tree, 6);
-  add (tree, 85);
-  delete (tree, 36);
-  delete (tree, 33);
-  delete (tree, 108);
-  add (tree, 229);
-  delete (tree, 269);
-  add (tree, 20);
-  add (tree, 170);
-  delete (tree, 154);
-  add (tree, 26);
-  add (tree, 211);
-  delete (tree, 167);
-  add (tree, 183);
-  add (tree, 292);
-  delete (tree, 2);
-  add (tree, 5);
-  delete (tree, 14);
-  delete (tree, 91);
-  add (tree, 172);
-  add (tree, 99);
-  delete (tree, 3);
-  delete (tree, 74);
-  delete (tree, 122);
-  add (tree, 87);
-  add (tree, 176);
-  delete (tree, 294);
-  add (tree, 169);
-  delete (tree, 41);
-  add (tree, 95);
-  delete (tree, 185);
-  add (tree, 218);
-  delete (tree, 62);
-  delete (tree, 175);
-  add (tree, 196);
-  delete (tree, 33);
-  delete (tree, 46);
-  add (tree, 30);
-  add (tree, 72);
-  delete (tree, 196);
-  delete (tree, 291);
-  add (tree, 198);
-  delete (tree, 181);
-  add (tree, 105);
-  delete (tree, 75);
-  add (tree, 30);
-  add (tree, 261);
-  delete (tree, 284);
-  delete (tree, 214);
-  delete (tree, 134);
-  add (tree, 153);
-  delete (tree, 46);
-  add (tree, 154);
-  add (tree, 266);
-  delete (tree, 272);
-  delete (tree, 150);
-  add (tree, 131);
-  delete (tree, 208);
-  add (tree, 241);
-  add (tree, 31);
-  add (tree, 151);
-  add (tree, 266);
-  delete (tree, 285);
-  add (tree, 178);
-  add (tree, 159);
-  add (tree, 203);
-  delete (tree, 266);
-  add (tree, 52);
-  delete (tree, 104);
-  add (tree, 243);
-  delete (tree, 12);
-  add (tree, 20);
-  delete (tree, 68);
-  print (tree);
-  delete (tree, 102);
-
-  gtk_css_rb_tree_unref (tree);
-}
-
-int
-main (int argc, char *argv[])
-{
-  g_test_init (&argc, &argv, NULL);
-  setlocale (LC_ALL, "C");
-  g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
-
-  g_test_add_func ("/csrbtree/crash", test_crash);
-
-  return g_test_run ();
-}
index 69dd63df7d353479822bf77ec3a84398b8afdf3c..912dbb409a05064177c26a75a986856564ad8651 100644 (file)
@@ -17,7 +17,7 @@ tests = [
   ['cellarea'],
   ['check-icon-names'],
   ['cssprovider'],
-  ['cssrbtree-crash', ['../../gtk/gtkcssrbtree.c'], ['-DGTK_COMPILATION', '-UG_ENABLE_DEBUG']],
+  ['rbtree-crash', ['../../gtk/gtkrbtree.c'], ['-DGTK_COMPILATION', '-UG_ENABLE_DEBUG']],
   ['defaultvalue'],
   ['entry'],
   ['filterlistmodel'],
diff --git a/testsuite/gtk/rbtree-crash.c b/testsuite/gtk/rbtree-crash.c
new file mode 100644 (file)
index 0000000..ec46c45
--- /dev/null
@@ -0,0 +1,286 @@
+/* GtkRBTree tests.
+ *
+ * Copyright (C) 2011, Red Hat, Inc.
+ * Authors: Benjamin Otte <otte@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <locale.h>
+
+#include <gtk/gtk.h>
+
+#include "gtk/gtkrbtreeprivate.h"
+
+typedef struct _Node Node;
+typedef struct _Aug Aug;
+
+struct _Node {
+  guint unused;
+};
+
+struct _Aug {
+  guint n_items;
+};
+
+static void
+augment (GtkRbTree *tree,
+         gpointer   _aug,
+         gpointer   _node,
+         gpointer   left,
+         gpointer   right)
+{
+  Aug *aug = _aug;
+  
+  aug->n_items = 1;
+
+  if (left)
+    {
+      Aug *left_aug = gtk_rb_tree_get_augment (tree, left);
+
+      aug->n_items += left_aug->n_items;
+    }
+
+  if (right)
+    {
+      Aug *right_aug = gtk_rb_tree_get_augment (tree, right);
+
+      aug->n_items += right_aug->n_items;
+    }
+}
+
+static Node *
+get (GtkRbTree *tree,
+     guint      pos)
+{
+  Node *node, *tmp;
+
+  node = gtk_rb_tree_get_root (tree);
+
+  while (node)
+    {
+      tmp = gtk_rb_tree_get_left (tree, node);
+      if (tmp)
+        {
+          Aug *aug = gtk_rb_tree_get_augment (tree, tmp);
+          if (pos < aug->n_items)
+            {
+              node = tmp;
+              continue;
+            }
+          pos -= aug->n_items;
+        }
+
+      if (pos < 1)
+        break;
+      pos--;
+
+      node = gtk_rb_tree_get_right (tree, node);
+    }
+
+  return node;
+}
+
+static void
+add (GtkRbTree *tree,
+     guint      pos)
+{
+  Node *node = get (tree, pos);
+
+  gtk_rb_tree_insert_before (tree, node);
+}
+
+static void
+delete (GtkRbTree *tree,
+        guint      pos)
+{
+  Node *node = get (tree, pos);
+
+  gtk_rb_tree_remove (tree, node);
+}
+
+static guint
+print_node (GtkRbTree  *tree,
+            Node       *node,
+            guint       depth,
+            const char *prefix,
+            guint       n)
+{
+  Node *child;
+
+  child = gtk_rb_tree_get_left (tree, node);
+  if (child)
+    n = print_node (tree, child, depth + 1, "/", n);
+  g_print ("%*s %u\n", 2 * depth, prefix, n);
+  n++;
+  child = gtk_rb_tree_get_right (tree, node);
+  if (child)
+    n = print_node (tree, child, depth + 1, "\\", n);
+
+  return n;
+}
+
+static void
+print (GtkRbTree *tree)
+{
+  print_node (tree, gtk_rb_tree_get_root (tree), 0, "", 0);
+}
+
+static void
+test_crash (void)
+{
+  GtkRbTree *tree;
+  guint i;
+
+  tree = gtk_rb_tree_new (Node, Aug, augment, NULL, NULL);
+
+  for (i = 0; i < 300; i++)
+    add (tree, i);
+  print (tree);
+  delete (tree, 144);
+  add (tree, 56);
+  delete (tree, 113);
+  delete (tree, 278);
+  delete (tree, 45);
+  delete (tree, 108);
+  delete (tree, 41);
+  add (tree, 56);
+  add (tree, 200);
+  delete (tree, 127);
+  delete (tree, 222);
+  add (tree, 80);
+  add (tree, 143);
+  add (tree, 216);
+  delete (tree, 177);
+  delete (tree, 193);
+  add (tree, 190);
+  delete (tree, 288);
+  add (tree, 45);
+  add (tree, 57);
+  add (tree, 211);
+  delete (tree, 103);
+  add (tree, 152);
+  delete (tree, 60);
+  add (tree, 185);
+  delete (tree, 167);
+  add (tree, 92);
+  delete (tree, 104);
+  delete (tree, 110);
+  delete (tree, 115);
+  add (tree, 32);
+  delete (tree, 44);
+  add (tree, 159);
+  add (tree, 271);
+  delete (tree, 35);
+  add (tree, 250);
+  delete (tree, 36);
+  add (tree, 284);
+  delete (tree, 82);
+  delete (tree, 248);
+  add (tree, 22);
+  delete (tree, 284);
+  add (tree, 88);
+  delete (tree, 182);
+  add (tree, 70);
+  add (tree, 55);
+  delete (tree, 6);
+  add (tree, 85);
+  delete (tree, 36);
+  delete (tree, 33);
+  delete (tree, 108);
+  add (tree, 229);
+  delete (tree, 269);
+  add (tree, 20);
+  add (tree, 170);
+  delete (tree, 154);
+  add (tree, 26);
+  add (tree, 211);
+  delete (tree, 167);
+  add (tree, 183);
+  add (tree, 292);
+  delete (tree, 2);
+  add (tree, 5);
+  delete (tree, 14);
+  delete (tree, 91);
+  add (tree, 172);
+  add (tree, 99);
+  delete (tree, 3);
+  delete (tree, 74);
+  delete (tree, 122);
+  add (tree, 87);
+  add (tree, 176);
+  delete (tree, 294);
+  add (tree, 169);
+  delete (tree, 41);
+  add (tree, 95);
+  delete (tree, 185);
+  add (tree, 218);
+  delete (tree, 62);
+  delete (tree, 175);
+  add (tree, 196);
+  delete (tree, 33);
+  delete (tree, 46);
+  add (tree, 30);
+  add (tree, 72);
+  delete (tree, 196);
+  delete (tree, 291);
+  add (tree, 198);
+  delete (tree, 181);
+  add (tree, 105);
+  delete (tree, 75);
+  add (tree, 30);
+  add (tree, 261);
+  delete (tree, 284);
+  delete (tree, 214);
+  delete (tree, 134);
+  add (tree, 153);
+  delete (tree, 46);
+  add (tree, 154);
+  add (tree, 266);
+  delete (tree, 272);
+  delete (tree, 150);
+  add (tree, 131);
+  delete (tree, 208);
+  add (tree, 241);
+  add (tree, 31);
+  add (tree, 151);
+  add (tree, 266);
+  delete (tree, 285);
+  add (tree, 178);
+  add (tree, 159);
+  add (tree, 203);
+  delete (tree, 266);
+  add (tree, 52);
+  delete (tree, 104);
+  add (tree, 243);
+  delete (tree, 12);
+  add (tree, 20);
+  delete (tree, 68);
+  print (tree);
+  delete (tree, 102);
+
+  gtk_rb_tree_unref (tree);
+}
+
+int
+main (int argc, char *argv[])
+{
+  g_test_init (&argc, &argv, NULL);
+  setlocale (LC_ALL, "C");
+  g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
+
+  g_test_add_func ("/csrbtree/crash", test_crash);
+
+  return g_test_run ();
+}